﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using System.Collections;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Windows.Interop;
using System.Windows.Media.Effects;
using System.Windows.Media.Animation;
using System.Text.RegularExpressions;
using System.Deployment;
using System.Deployment.Application;
using System.Threading;

namespace WGM_Client_Net35
{
 
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        [DllImport("user32.dll")]
        private static extern int FlashWindowEx(ref FLASHWINFO pwfi);

        [DllImport("user32.dll")]
        private static extern IntPtr GetForegroundWindow();

        private struct FLASHWINFO
        {
            public Int32 cbSize;
            public IntPtr hwnd;
            public Int32 dwFlags;
            public Int32 uCount;
            public Int32 dwTimeout;
        }
        private bool _iconBlinking = false;
        public ConnectionHandlerObject ConnectionHandler { get; set; }
        ObservableCollection<TabListItem> _tabs;
        private System.Windows.Forms.NotifyIcon _notifyIcon  = new System.Windows.Forms.NotifyIcon();
        public System.Windows.Forms.NotifyIcon TrayIcon 
        { 
            get; 
            private set; 
        }

        public MainWindow()
        {
            InitializeComponent();

            _notifyIcon.Icon = new System.Drawing.Icon("app.ico");
            TrayIcon = _notifyIcon;
            _notifyIcon.Visible = true;
            
            System.Windows.Forms.MenuItem localOptionsTrayMenu = new System.Windows.Forms.MenuItem("Local Options");
            localOptionsTrayMenu.Click += new EventHandler(localOptionsTrayMenu_Click);
            System.Windows.Forms.MenuItem exitTrayMenu = new System.Windows.Forms.MenuItem("Exit");
            System.Windows.Forms.MenuItem popupTrayMenu = new System.Windows.Forms.MenuItem("Popups");
            System.Windows.Forms.MenuItem popupTrayMenuNewUser = new System.Windows.Forms.MenuItem("Online User Popup");
            System.Windows.Forms.MenuItem popupTrayMenuLeavingUser = new System.Windows.Forms.MenuItem("Leaving User Popup");
            System.Windows.Forms.MenuItem popupTrayMenuNewGlobalMessage = new System.Windows.Forms.MenuItem("New Global Message Popup");
            System.Windows.Forms.MenuItem popupTrayMenuNewPrivateMessage = new System.Windows.Forms.MenuItem("New Private Message Popup");
            System.Windows.Forms.MenuItem onlineOptionsTrayMenu = new System.Windows.Forms.MenuItem("Online Options");

            onlineOptionsTrayMenu.Click += new EventHandler(onlineOptionsTrayMenu_Click);
            popupTrayMenuNewUser.Checked = Properties.Settings.Default.PopupContactOnline;
            popupTrayMenuLeavingUser.Checked = Properties.Settings.Default.PopupContactLeaving;
            popupTrayMenuNewGlobalMessage.Checked = Properties.Settings.Default.PopupNewGlobalMessage;
            popupTrayMenuNewPrivateMessage.Checked = Properties.Settings.Default.PopupNewPrivateMessage;

            popupTrayMenuNewUser.Click += new EventHandler(popupTrayMenuNewUser_Click);
            popupTrayMenuLeavingUser.Click +=new EventHandler(popupTrayMenuLeavingUser_Click);
            popupTrayMenuNewGlobalMessage.Click += new EventHandler(popupTrayMenuNewGlobalMessage_Click);
            popupTrayMenuNewPrivateMessage.Click += new EventHandler(popupTrayMenuNewPrivateMessage_Click);
            popupTrayMenu.Click += new EventHandler(popupTrayMenu_Click);
            exitTrayMenu.Click += new EventHandler(exitTrayMenu_Click);

            _notifyIcon.ContextMenu = new System.Windows.Forms.ContextMenu();

            popupTrayMenu.MenuItems.Add(popupTrayMenuNewUser);
            popupTrayMenu.MenuItems.Add(popupTrayMenuLeavingUser);
            popupTrayMenu.MenuItems.Add(popupTrayMenuNewGlobalMessage);
            popupTrayMenu.MenuItems.Add(popupTrayMenuNewPrivateMessage);

            _notifyIcon.ContextMenu.Popup += new EventHandler(ContextMenu_Popup);

            _notifyIcon.ContextMenu.MenuItems.Add(popupTrayMenu);
            _notifyIcon.ContextMenu.MenuItems.Add(onlineOptionsTrayMenu);
            _notifyIcon.ContextMenu.MenuItems.Add(localOptionsTrayMenu);
            _notifyIcon.ContextMenu.MenuItems.Add("-"); 
            _notifyIcon.ContextMenu.MenuItems.Add(exitTrayMenu);
            
            
            _notifyIcon.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(_notifyIcon_MouseDoubleClick);
            _tabs = new ObservableCollection<TabListItem>();

            
        }
        public void SetSelectedTab(TabListItem tli)
        {            
            if (tli.IncomingListName == "main_conversation")
            {
                _remoteImage.Background = new ImageBrush(new BitmapImage(new Uri(".\\images\\mainicon.png", UriKind.RelativeOrAbsolute)));
                _remoteDisplayName.ToolTip = _remoteDisplayName.Text = "Main Conversation";
                _remoteDisplayStatus.ToolTip = _remoteDisplayStatus.Text = "...by HartLabs";

            }
            else
            {            
                ContactListItem cli =  ConnectionHandler.GetContactListItem(tli.IncomingListName);
                _remoteDisplayName.ToolTip = _remoteDisplayName.Text = cli.DisplayName;
                _remoteDisplayStatus.ToolTip = _remoteDisplayStatus.Text = cli.DisplayStatus;
                if(cli.DisplayImage!=null)
                    _remoteImage.Background =new ImageBrush( HelperFunctions.GetBitmapFromImage(cli.DisplayImage ));             
                else
                    _remoteImage.Background = new ImageBrush(new BitmapImage(new Uri(".\\images\\blank.png", UriKind.RelativeOrAbsolute)));

            }
            DoubleAnimation fadeIn = new DoubleAnimation(0, 1, new Duration(new TimeSpan(0, 0, 3)));
            _remoteImage.BeginAnimation(Image.OpacityProperty, fadeIn);
            
        }
        private void SetReflection()
        {


        }
        void onlineOptionsTrayMenu_Click(object sender, EventArgs e)
        {
            OnlineOptionsMenu_Click(sender, null);
        }

        void ContextMenu_Popup(object sender, EventArgs e)
        {
            _notifyIcon.ContextMenu.MenuItems[0].MenuItems[0].Checked = Properties.Settings.Default.PopupContactOnline;
            _notifyIcon.ContextMenu.MenuItems[0].MenuItems[1].Checked = Properties.Settings.Default.PopupContactLeaving;
            _notifyIcon.ContextMenu.MenuItems[0].MenuItems[2].Checked = Properties.Settings.Default.PopupNewGlobalMessage;
            _notifyIcon.ContextMenu.MenuItems[0].MenuItems[3].Checked = Properties.Settings.Default.PopupNewPrivateMessage;
        }

        void popupTrayMenuNewPrivateMessage_Click(object sender, EventArgs e)
        {
            System.Windows.Forms.MenuItem mi = sender as System.Windows.Forms.MenuItem;
            mi.Checked = !mi.Checked;
            Properties.Settings.Default.PopupNewPrivateMessage = mi.Checked;
        }

        void popupTrayMenuNewGlobalMessage_Click(object sender, EventArgs e)
        {
            System.Windows.Forms.MenuItem mi = sender as System.Windows.Forms.MenuItem;
            mi.Checked = !mi.Checked;
            Properties.Settings.Default.PopupNewGlobalMessage = mi.Checked;
        }

        void  popupTrayMenuLeavingUser_Click(object sender, EventArgs e)
        {
            System.Windows.Forms.MenuItem mi = sender as System.Windows.Forms.MenuItem;
            mi.Checked = !mi.Checked;
            Properties.Settings.Default.PopupContactLeaving = mi.Checked;
        }

        void popupTrayMenuNewUser_Click(object sender, EventArgs e)
        {
            System.Windows.Forms.MenuItem mi = sender as System.Windows.Forms.MenuItem;
            mi.Checked = !mi.Checked;
            Properties.Settings.Default.PopupContactOnline = mi.Checked;
        }

        void popupTrayMenu_Click(object sender, EventArgs e)
        {

        }

        void localOptionsTrayMenu_Click(object sender, EventArgs e)
        {
            LocalOptionsMenu_Click(sender, null);
        }

        void exitTrayMenu_Click(object sender, EventArgs e)
        {
            LogOffMenu_Click(sender, new RoutedEventArgs());
        }

        void _notifyIcon_MouseDoubleClick(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            this.Show();
            this.Activate();
        }

        public void AddMainWindow()
        {
            TabListItem mainTab = new TabListItem(this, ConnectionHandler.MyUserOptions, "Main Conversation", "main_conversation", "main_conversation",  Colors.Green.ToString(), true);
            mainTab.CloseButtonVisibility = Visibility.Collapsed;
            _tabs.Add(mainTab);
            _tabControl.ItemsSource = _tabs;
            _tabControl.SelectedIndex = 0;
        }
        public void SetConnectionStatus(object greenVal)
        {
            try
            {
                int iGreen = (int)greenVal;
                byte green = (byte)iGreen;
                if (green < 0)
                    green = 0;
                if (green > 255)
                    green = 255;
                byte red = (byte)(255 - green);

                _connectionDisplay.Fill = new SolidColorBrush(Color.FromRgb(red, green, 0));
                
                if (green == 0)
                {
                    _notifyIcon.Text = "WGM Beta - Connection Error";
                }
                else
                {
                    _notifyIcon.Text = "WGM Beta - Online";
                }
            }
            catch { }
            
        }
        public void SetConnectionHandler(ConnectionHandlerObject ch)
        {
            ConnectionHandler = ch;
            ch.SetClientWindow(this);
            if (ch.CurrentUserName != "wayne")
            {
                //AdminMenu.Visibility = Visibility.Collapsed;
                AdminMenu.IsEnabled = false;
            }
            ch.Execute(System.Windows.Threading.Dispatcher.CurrentDispatcher);
            _contactListView.ItemsSource = ch.ContactListItems;
            BackgroundWorker imageWorker = new BackgroundWorker();
            imageWorker.DoWork += new DoWorkEventHandler(imageWorker_DoWork);
            imageWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(imageWorker_RunWorkerCompleted);
            imageWorker.RunWorkerAsync();
        }
        public void SetCurrentDisplayInfo(string displayName, string displayStatus)
        {
            _displayName.ToolTip = _displayName.Text = displayName;
            _displayStatus.ToolTip = _displayStatus.Text = displayStatus;
            
        }
        public void SetCurrentImage(System.Drawing.Image currentImage)
        {
            if(currentImage !=null)
                _displayImage.Background = new ImageBrush(HelperFunctions.GetBitmapFromImage(currentImage));
            else
                _displayImage.Background = new ImageBrush(new BitmapImage(new Uri(".\\images\\blank.png", UriKind.RelativeOrAbsolute)));

        }
        void imageWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Result != null)
            {
                byte[] imageArr = e.Result as byte[];
                System.Drawing.Image currentImage = HelperFunctions.ByteArrayToImage(imageArr);

                DoubleAnimation fadeIn = new DoubleAnimation(0, 1, new Duration(new TimeSpan(0, 0, 3)));
                _displayImage.BeginAnimation(Image.OpacityProperty, fadeIn);
                _displayImage.Background = new ImageBrush(HelperFunctions.GetBitmapFromImage(currentImage));
                SetReflection();

            }
            else
            {
                _displayImage.Background = new ImageBrush(new BitmapImage(new Uri(".\\images\\blank.png", UriKind.RelativeOrAbsolute)));

            }

        }

        void imageWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            e.Result = ConnectionHandler.RetrieveUserImage(ConnectionHandler.CurrentUserName);
        }
        public void ReceiveMessage(string userName, LocalMessageItem message, bool isGlobal)
        {
            try
            {
                ContactListItem cli = ConnectionHandler.GetContactListItem(userName);
                if (cli != null && Properties.Settings.Default.FlashContactListUserOnNewMessage)
                {
                    //cli.FlashContactItem();
                }
                if (isGlobal)
                {
                    _tabs[0].AddMessage(message, ConnectionHandler);
                    if (_tabs[0].IsTabSelected == false && Properties.Settings.Default.FlashTabOnNewMessage)
                        _tabs[0].FlashTabItem();

                    if (this.Visibility == Visibility.Hidden && Properties.Settings.Default.PopupNewGlobalMessage)
                    {
                        if (cli != null)
                        {
                            
                            _notifyIcon.ShowBalloonTip(1500, "Global Message from " + HelperFunctions.GetIntroString(cli.ContactData as WGM_Service.UserOptions), message.MessageText, System.Windows.Forms.ToolTipIcon.Info);
                        }
                    }
                }
                else
                {
                    TabListItem tli = FindOpenTab(userName, false, true);
                    tli.AddMessage(message, ConnectionHandler);
                    if (tli.IsTabSelected == false && Properties.Settings.Default.FlashTabOnNewMessage)
                        tli.FlashTabItem();

                    if (this.Visibility == Visibility.Hidden)
                    {
                        if (cli != null)
                        {
                            if (Properties.Settings.Default.PopupNewPrivateMessage)
                                _notifyIcon.ShowBalloonTip(1500, "Private Message from " + HelperFunctions.GetIntroString(cli.ContactData as WGM_Service.UserOptions), message.MessageText, System.Windows.Forms.ToolTipIcon.Info);
                            else
                            {
                                if (!_iconBlinking)
                                {
                                    Thread blinkIcon = new Thread(new ThreadStart(BlinkIconThreadProc));
                                    blinkIcon.IsBackground = true;
                                    blinkIcon.Start();
                                }
                            }
                        }                        
                    }
                }

                if (GetForegroundWindow() != new WindowInteropHelper(this).Handle && Properties.Settings.Default.FlashMainWindowOnNewMessage == true)
                    FlashWindow(new WindowInteropHelper(this).Handle);
            }
            catch { }
        }
        private void BlinkIconThreadProc()
        {
            _iconBlinking = true;
            while (this.Visibility == Visibility.Hidden)
            {
                _notifyIcon.Icon = new System.Drawing.Icon("app2.ico");
                Thread.Sleep(500);
                _notifyIcon.Icon = new System.Drawing.Icon("app.ico");
                Thread.Sleep(500);
            }
            _notifyIcon.Icon = new System.Drawing.Icon("app.ico");
            _iconBlinking = false;
        }
        private void TextBox_KeyUp(object sender, KeyEventArgs e)
        {
            try
            {
                BindableRichTextBox t = sender as BindableRichTextBox;
                if (e.Key == Key.Enter && e.KeyboardDevice.Modifiers == ModifierKeys.Control)
                {
                    t.CaretPosition.InsertLineBreak();

                    t.CaretPosition = t.CaretPosition.DocumentEnd;
                }
                if (e.Key == Key.Enter && e.KeyboardDevice.Modifiers == ModifierKeys.None)
                {
                    e.Handled = true;
                    TextPointer from = t.CaretPosition.DocumentStart;
                    TextPointer to = t.CaretPosition;
                    t.Selection.Select(from, to);
                    t.Selection.Text = t.Selection.Text.Remove(t.Selection.Text.Length - 2, 2);



                    t.SelectAll();
                    t.Selection.Text = t.Selection.Text.Remove(t.Selection.Text.Length - 2);
                    string text = t.Selection.Text;
                    string user = t.Tag as string;
                    WGM_Service.WGMMessage sendMessage = null;
                    if (_tabs[0].IsTabSelected == false)
                    {
                        sendMessage = new WGM_Client_Net35.WGM_Service.WGMMessage();
                        sendMessage.MessageType = WGM_Client_Net35.WGM_Service.MessageTypes.PRIVATE_MESSAGE;
                        sendMessage.ReceiverLogon = user;
                        sendMessage.SenderLogon = ConnectionHandler.CurrentUserName;
                        sendMessage.TimeStamp = DateTime.Now;
                        sendMessage.Message = text;
                        if (ConnectionHandler.ConnectionStatus == 0)
                        {
                        }

                    }
                    if (_tabs[0].IsTabSelected == true)
                    {
                        sendMessage = new WGM_Client_Net35.WGM_Service.WGMMessage();
                        sendMessage.MessageType = WGM_Client_Net35.WGM_Service.MessageTypes.GLOBAL_MESSAGE;
                        sendMessage.SenderLogon = ConnectionHandler.CurrentUserName;
                        sendMessage.TimeStamp = DateTime.Now;
                        sendMessage.Message = text;
                        if (ConnectionHandler.ConnectionStatus == 0)
                        {
                        }

                    }

                    t.Selection.Text = "";
                    if ((sendMessage.Message as string).Trim() == "")
                        return;
                    ConnectionHandler.SendMessage(sendMessage);

                }
                else
                {

                }
            }
            catch { }
            
        }
        public void SendFailure(object obj)
        {
            try
            {
                
                WGM_Service.WGMMessage message = obj as WGM_Service.WGMMessage;
                if (message.MessageType == WGM_Client_Net35.WGM_Service.MessageTypes.GLOBAL_MESSAGE)
                {
                    _tabs[0].AddMessage(new LocalMessageItem(DateTime.Now, "Your message \"" + message.Message as string + "\" was not able to be sent due to connection issues...", Colors.Red, null, true, Colors.DarkGray.ToString()), ConnectionHandler);

                }
                else
                {
                    TabListItem tli = FindOpenTab(message.ReceiverLogon, false, true);
                    tli.AddMessage(new LocalMessageItem(DateTime.Now, "Your message \"" + message.Message as string + "\" was not able to be sent due to connection issues...", Colors.Red, null, true, Colors.DarkGray.ToString()), ConnectionHandler);
                }
                if (GetForegroundWindow() != new WindowInteropHelper(this).Handle && Properties.Settings.Default.FlashMainWindowOnNewMessage == true)
                    FlashWindow(new WindowInteropHelper(this).Handle);
            }
            catch { }
        }
        private void BindableRichTextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            BindableRichTextBox rtb = sender as BindableRichTextBox;
            if(Properties.Settings.Default.AutoScrollMessageWindow == true)
                rtb.ScrollToEnd();
        }
        public void FlashWindow(IntPtr handle)
        {
            //int FLASHW_STOP = 0;
            //int FLASHW_CAPTION = 1;
            //int FLASHW_TRAY = 2;
            int FLASHW_ALL = 3;
            //int FLASHW_TIMER = 4;
            int FLASHW_TIMERNOFG = 12;
            FLASHWINFO pwfi = new FLASHWINFO();
            pwfi.cbSize = Marshal.SizeOf(pwfi);
            pwfi.hwnd = handle;
            pwfi.dwFlags = FLASHW_ALL | FLASHW_TIMERNOFG;
            pwfi.uCount = 3;
            pwfi.dwTimeout = 0;
            Int32 intRet = FlashWindowEx(ref pwfi);
        }
        private void viewbox_MouseDown(object sender, MouseButtonEventArgs e)
        {
            
            TextBlock clickedBtn = sender as TextBlock;
            string userName = clickedBtn.Tag as string;
            for (int count = 0; count < _tabs.Count; count++)
            {
                if (_tabs[count].OutgoingTBName == userName && count != 0)
                {
                    if (_tabs[count].IsTabSelected)
                    {
                        _tabs[count - 1].IsTabSelected = true;
                        _tabs[count].IsTabSelected = false;
                    }
                    
                    _tabs.RemoveAt(count);
                }
            }
        }
        private void ContactListDoubleClick(object sender, RoutedEventArgs e)
        {
            ListBoxItem item = sender as ListBoxItem;
            ContactListItem cli = item.Content as ContactListItem;
            TabListItem tli = FindOpenTab(cli.UserName,true, true);
            if (tli != null)
                tli.SetTabData(cli.ContactData as WGM_Service.UserOptions, cli.IsContactOnline);
        }

        public TabListItem FindOpenTab(string userName, bool selectTab, bool makeNew)
        {
            foreach (TabListItem item in _tabs)
            {
                if (item.OutgoingTBName.ToLower().Trim() == userName.ToLower().Trim())
                {
                    if(selectTab)
                        item.IsTabSelected = true;
                    return item;
                }
            }
            if (makeNew == false)
                return null;
            ContactListItem contact = ConnectionHandler.GetContactListItem(userName);
            TabListItem newTab = new TabListItem(this, ConnectionHandler.MyUserOptions, contact.DisplayName, contact.UserName, contact.UserName,  HelperFunctions.GetNewColour(contact.ContactData as WGM_Service.UserOptions).ToString(),contact.IsContactOnline);
            _tabs.Add(newTab);       
            if(selectTab)
                newTab.IsTabSelected = true;

            newTab.SetTabData(contact.ContactData as WGM_Service.UserOptions, contact.IsContactOnline);
            return newTab;
        }

        private void Window_Closing(object sender, CancelEventArgs e)
        {
            this.Hide();
            e.Cancel = true;

        }

        private void LogOffMenu_Click(object sender, RoutedEventArgs e)
        {
            grid.IsEnabled = false;
            _notifyIcon.Visible = false;      
            BackgroundWorker bgw = new BackgroundWorker();
            bgw.DoWork += new DoWorkEventHandler(bgw_DoWork);
            bgw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgw_RunWorkerCompleted);
            bgw.RunWorkerAsync();
              
            
        }

        void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            Properties.Settings.Default.Save();
            Application.Current.Shutdown();
        }

        void bgw_DoWork(object sender, DoWorkEventArgs e)
        {
            ConnectionHandler.LogOff();
        }

        private void AboutMenuItem_Click(object sender, RoutedEventArgs e)
        {

            if (ApplicationDeployment.IsNetworkDeployed)
            {
                MessageBox.Show("Wayne's Global Messenger Beta\r\nVersion " + ApplicationDeployment.CurrentDeployment.CurrentVersion.ToString(), "Wayne's Global Messenger", MessageBoxButton.OK, MessageBoxImage.Information);
            }
        }

        private void LocalOptionsMenu_Click(object sender, RoutedEventArgs e)
        {
            
            LocalOptionsWindow lOptions = new LocalOptionsWindow();
            lOptions.ShowDialog();
        }

        private void DebugMenu_Click(object sender, RoutedEventArgs e)
        {
            
        }

        private void AdminMenu_Click(object sender, RoutedEventArgs e)
        {
            AdminWindow aw = new AdminWindow(this);
            aw.ShowDialog();
        }

        private void OnlineOptionsMenu_Click(object sender, RoutedEventArgs e)
        {
            OnlineOptionsWindow oow = new OnlineOptionsWindow(ConnectionHandler.MyUserOptions, ConnectionHandler,this);
            oow.ShowDialog();
        }
        public void SetAllTabsData(WGM_Service.UserOptions options)
        {
            foreach (TabListItem tli in _tabs)
            {
                tli.SetMyOnlineOptions(options);               
            }
        }

        private void _displayImage_MouseDown(object sender, MouseButtonEventArgs e)
        {
            OnlineOptionsWindow oow = new OnlineOptionsWindow(ConnectionHandler.MyUserOptions, ConnectionHandler, this);
            oow.ShowDialog();
        }

        internal void SetRemoteDisplayImage(object userName)
        {
            TabListItem tab = FindOpenTab(userName as string, false, false);
            if (tab != null)
            {
                if (tab.IsTabSelected)
                {
                    SetSelectedTab(tab);
                }
            }
        }
    }

}
